home *** CD-ROM | disk | FTP | other *** search
/ Workbench Design / WB Collection.iso / workbench werkzeuge / memory & system tools / tinymeter / source / tinymeter_main / gaugeclass.c < prev    next >
C/C++ Source or Header  |  1996-04-07  |  32KB  |  857 lines

  1. /*
  2. ** gaugeclass V0.9 by Tinic Urou
  3. **
  4. ** Class implementation
  5. **
  6. ** tested compilers:
  7. **
  8. ** · DCC 2.6.2
  9. ** · GCC 2.7.0 with libnix V1.0 (libnix is necessary!!)
  10. **
  11. */
  12.  
  13. #include <exec/types.h>
  14. #include <exec/memory.h>
  15. #include <dos/dos.h>
  16. #include <dos/dosextens.h>
  17. #include <intuition/intuition.h>
  18. #include <intuition/gadgetclass.h>
  19. #include <intuition/intuitionbase.h>
  20. #include <intuition/classusr.h>
  21. #include <intuition/imageclass.h>
  22. #include <intuition/gadgetclass.h>
  23. #include <intuition/cghooks.h>
  24. #include <intuition/icclass.h>
  25. #include <intuition/classes.h>
  26. #include <intuition/sghooks.h>
  27. #include <intuition/screens.h>
  28. #include <graphics/gfxbase.h>
  29. #include <graphics/text.h>
  30. #include <graphics/gfxmacros.h>
  31. #include <utility/tagitem.h>
  32. #include <utility/hooks.h>
  33. #include <string.h>
  34. #include "gaugeclass.h"
  35.  
  36. #define col_label       0
  37. #define col_format      1
  38. #define col_base        2
  39. #define col_current     3
  40. #define col_negative    4
  41. #define col_bright      5
  42. #define col_dark        6
  43. #define col_bg          7
  44.  
  45. #define ind_centered    0
  46. #define ind_left        1
  47. #define ind_right       2
  48.  
  49. struct GaugeData
  50. {
  51.         ULONG   min;
  52.         ULONG   max;
  53.         ULONG   current;
  54.         ULONG   base;
  55.         ULONG   old_cur;
  56.         ULONG   old_bas;
  57.         WORD   labelpos;
  58.         UBYTE   fmtind;
  59.  
  60.         ULONG   type;
  61.  
  62.         char    *txtlbl;
  63.         char    *txtfmt;
  64.  
  65.         struct  GAU_Color Colors[GAU_UsedColors];
  66.  
  67.         BOOL    Style3D;
  68.         BOOL    StyleBorder;
  69.         BOOL    StyleBackground;
  70.         BOOL    StyleShadowLabel;
  71.         BOOL    StyleNoGauge;
  72.         BOOL    StyleNoFormat;
  73.         BOOL    StyleNoBase;
  74.  
  75.         struct  TextFont *textFont;
  76.  
  77.         ULONG   Pens[GAU_UsedColors];
  78.         BOOL    PorC[GAU_UsedColors];
  79.  
  80.         BOOL    InitNotDone;
  81.  
  82.         struct  RastPort *nolock_rp;
  83.  
  84.         LONG   histpos;
  85.  
  86.         WORD   text_y;
  87.         struct  Locale *locale;
  88.         char    clocktxt[256];
  89.  
  90.         struct  RastPort   *bg_buffer;
  91.         struct  RastPort   *wk_buffer;
  92.         struct  RastPort   *hs_buffer;
  93.  
  94.         WORD   clockpos;
  95. };
  96.  
  97. extern ULONG DoSuperMethodA( struct IClass *cl, Object *obj, Msg message );
  98. extern ULONG DoMethod( Object *obj, unsigned long MethodID, ... );
  99. extern ULONG HookEntry();
  100.  
  101. #ifdef __GNUC__
  102. ULONG dispatchGaugeGadget();
  103. #else
  104. static ULONG dispatchGaugeGadget(__a0 Class *cl,__a2 Object *o,__a1 Msg msg);
  105. #endif
  106.  
  107. static ULONG renderGauge(Class *cl,struct Gadget *g, struct gpRender *msg);
  108. void SPrintf(STRPTR buffer, STRPTR format, ...);
  109.  
  110. Class *initGaugeGadgetClass(void)
  111. {
  112.     Class *cl;
  113.     if( cl = (Class *)MakeClass( NULL, "gadgetclass", NULL, sizeof(struct GaugeData), 0) )
  114.     {
  115.         cl->cl_Dispatcher.h_Entry = (ULONG(*)()) HookEntry;
  116.         cl->cl_Dispatcher.h_SubEntry = (ULONG(*)()) dispatchGaugeGadget;
  117.         return(cl);
  118.     }
  119. }
  120.  
  121. BOOL freeGaugeGadgetClass( Class *cl )
  122. {
  123.     return FreeClass(cl);
  124. }
  125.  
  126. struct TextFont *OpenTopaz()
  127. {
  128.     struct TextAttr topaz_font =
  129.     {
  130.         "topaz.font",
  131.         8,
  132.         0,
  133.         FPF_ROMFONT,
  134.     };
  135.     return((struct TextFont *)OpenFont( &topaz_font));
  136. }
  137.  
  138. void SPrintf(STRPTR buffer, STRPTR format, ...)
  139. {
  140.     struct Library *SysBase= *((void **)4L);
  141.     RawDoFmt( format, (APTR)(&format+1), (void (*)())"\x16\xc0\x4E\x75", buffer);
  142. }
  143.  
  144. my_strlen(char s[])           /*liefert die Laenge von s */
  145. {
  146.    int i=0;
  147.    while (s[i]!='\0')++i;
  148.    return(i);
  149. }
  150.  
  151. struct GAU_Color dummycol={ TRUE, 0, 0, 0 };
  152. struct GAU_Color *GetGaugePen(WORD pen){ dummycol.red=pen; return(&dummycol); }
  153.  
  154. GetGaugePenNew(struct gpRender *msg,struct GaugeData *inst,struct GAU_Color *col,ULONG number)
  155. {
  156.     if(col->pen)
  157.     {
  158.         inst->PorC[number]=FALSE;
  159.         inst->Pens[number]=col->red;
  160.     }
  161.     else
  162.     {
  163.         inst->PorC[number]=TRUE;
  164.         inst->Pens[number]=ObtainBestPenA(msg->gpr_GInfo->gi_Screen->ViewPort.ColorMap, col->red, col->green, col->blue, 0L);
  165.     }
  166. }
  167.  
  168. ReleasePenNew(struct gpRender *msg,struct GaugeData *inst,ULONG number)
  169. {
  170. /*    if(inst->PorC[number])
  171.     {
  172.         ReleasePen(msg->gpr_GInfo->gi_Screen->ViewPort.ColorMap,inst->Pens[number]);
  173.         inst->PorC[number]=FALSE;
  174.     }*/
  175. }
  176.  
  177.  
  178. ULONG newGauge(Class *cl,struct Gadget *g,struct gpRender *msg,struct GaugeData *inst)
  179. {
  180.     ULONG    retval;
  181.     struct   TagItem *ti;
  182.  
  183.     ti      = ((struct opSet *)msg)->ops_AttrList;
  184.     if(inst->textFont = (struct TextFont *)GetTagData(GAU_TextFont,OpenTopaz(),ti))
  185.     {
  186.         struct RastPort *dummy;
  187.         if(dummy=(struct RastPort *)AllocVec(sizeof(struct RastPort),0L))
  188.         {
  189.             InitRastPort(dummy);
  190.             dummy->Font=inst->textFont;
  191.             {
  192.                 inst->min               = GetTagData(GAU_Min,        0, ti);
  193.                 inst->max               = GetTagData(GAU_Max,    65535L, ti);
  194.                 inst->current           = GetTagData(GAU_Current,32162L, ti);
  195.                 inst->base              = GetTagData(GAU_Base,   16384L, ti);
  196.                 inst->txtfmt            = (char *)GetTagData(GAU_TextFormat, "%td", ti);
  197.                 inst->txtlbl            = (char *)GetTagData(GAU_Label, "Gauge", ti);
  198.                 inst->labelpos          = GetTagData(GAU_LabelPos,TextLength(dummy,inst->txtlbl,my_strlen(inst->txtlbl))+4, ti);
  199.  
  200.                 inst->Style3D           = GetTagData(GAU_3D,  TRUE, ti);
  201.                 inst->StyleBorder       = GetTagData(GAU_Border, TRUE, ti);
  202.                 inst->StyleBackground   = GetTagData(GAU_Background, FALSE, ti);
  203.                 inst->StyleShadowLabel  = GetTagData(GAU_ShadowLabel, FALSE, ti);
  204.                 inst->StyleNoGauge      = GetTagData(GAU_NoGauge,   FALSE, ti);
  205.                 inst->StyleNoFormat     = GetTagData(GAU_NoFormat,  FALSE, ti);
  206.                 inst->StyleNoBase       = GetTagData(GAU_NoBase,  FALSE, ti);
  207.                 inst->fmtind            = GetTagData(GAU_FmtIndent, FALSE, ti);
  208.                 inst->type              = GetTagData(GAU_Type, GAU_Type_gauge, ti);
  209.                 if(inst->type==GAU_Type_clock) inst->locale = (struct Locale *)OpenLocale(NULL);
  210.  
  211.                 CopyMem(GetTagData(GAU_ColLabel     , GetGaugePen(2), ti), &inst->Colors[col_label],sizeof(struct GAU_Color));
  212.                 CopyMem(GetTagData(GAU_ColFormat    , GetGaugePen(2), ti), &inst->Colors[col_format],sizeof(struct GAU_Color));
  213.                 CopyMem(GetTagData(GAU_ColBase      , GetGaugePen(1), ti), &inst->Colors[col_base],sizeof(struct GAU_Color));
  214.                 CopyMem(GetTagData(GAU_ColCurrent   , GetGaugePen(3), ti), &inst->Colors[col_current],sizeof(struct GAU_Color));
  215.                 CopyMem(GetTagData(GAU_ColNegative  , GetGaugePen(1), ti), &inst->Colors[col_negative],sizeof(struct GAU_Color));
  216.                 CopyMem(GetTagData(GAU_ColBrightEdg , GetGaugePen(2), ti), &inst->Colors[col_bright],sizeof(struct GAU_Color));
  217.                 CopyMem(GetTagData(GAU_ColDarkEdg   , GetGaugePen(1), ti), &inst->Colors[col_dark],sizeof(struct GAU_Color));
  218.                 CopyMem(GetTagData(GAU_ColBackground, GetGaugePen(0), ti), &inst->Colors[col_bg],sizeof(struct GAU_Color));
  219.  
  220.                 inst->InitNotDone=TRUE;
  221.  
  222.                 retval=(ULONG)g;
  223.             }
  224.             FreeVec(dummy);
  225.         }
  226.         else { retval=0L;}
  227.     }
  228.     else { retval=0L;}
  229.  
  230.     return(retval);
  231. }
  232.  
  233. freeRPorts(struct GaugeData *inst)
  234. {
  235.     if(inst->bg_buffer)
  236.     {
  237.         FreeBitMap(inst->bg_buffer->BitMap);
  238.         FreeVec(inst->bg_buffer);
  239.         inst->bg_buffer=0L;
  240.     }
  241.  
  242.     if(inst->wk_buffer)
  243.     {
  244.         FreeBitMap(inst->wk_buffer->BitMap);
  245.         FreeVec(inst->wk_buffer);
  246.         inst->wk_buffer=0L;
  247.     }
  248.  
  249.     if(inst->hs_buffer)
  250.     {
  251.         FreeBitMap(inst->hs_buffer->BitMap);
  252.         FreeVec(inst->hs_buffer);
  253.         inst->hs_buffer=0L;
  254.     }
  255.  
  256. }
  257.  
  258. ULONG disposeGauge(Class *cl,struct Gadget *g,struct gpRender *msg)
  259. {
  260.     struct GaugeData *inst;
  261.     ULONG  i;
  262.     inst=INST_DATA(cl,g);
  263.     CloseLocale(inst->locale);
  264. /*    for(i=0;i<8;i++)
  265.     {
  266.         if(inst->PorC[i]==TRUE)
  267.         {
  268.             ReleasePen(msg->gpr_GInfo->gi_Screen->ViewPort.ColorMap,inst->Pens[i]);
  269.             inst->PorC[i]=FALSE;
  270.         }
  271.     }*/
  272.     freeRPorts(inst);
  273. }
  274.  
  275. ULONG getGauge(Class *cl,struct Gadget *g,struct gpRender *msg)
  276. {
  277.     struct GaugeData *inst;
  278.     inst=INST_DATA(cl,g);
  279.     switch (((struct opGet *)msg)->opg_AttrID)
  280.     {
  281.         case    GAU_RPBackground:
  282.                 *(((struct opGet *)msg)->opg_Storage)=(ULONG)inst->bg_buffer;
  283.                 break;
  284.         case    GAU_Base:
  285.                 *(((struct opGet *)msg)->opg_Storage)=(ULONG)inst->base;
  286.                 break;
  287.         case    GAU_Current:
  288.                 *(((struct opGet *)msg)->opg_Storage)=(ULONG)inst->current;
  289.                 break;
  290.         default:
  291.                 return((ULONG)FALSE);
  292.                 break;
  293.     }
  294.     return((ULONG)TRUE);
  295. }
  296.  
  297. setGauge(Class *cl,struct Gadget *g,struct gpRender *msg)
  298. {
  299.     struct TagItem      *ti,*tstate=((struct opSet *)msg)->ops_AttrList;
  300.     struct GaugeData    *inst;
  301.     struct RastPort     *rp;
  302.     ULONG  t_data;
  303.  
  304.     inst=INST_DATA(cl,g);
  305.     while(ti=(struct TagItem *)NextTagItem(&tstate))
  306.     {
  307.         t_data=(ULONG)ti->ti_Data;
  308.         switch(ti->ti_Tag)
  309.         {
  310.             case    GAU_Current:
  311.                     inst->current=  (ULONG)t_data;
  312.                     break;
  313.             case    GAU_Base:
  314.                     inst->base=     (ULONG)t_data;
  315.                     break;
  316.             case    GAU_Max:
  317.                     inst->max=      (ULONG)t_data;
  318.                     break;
  319.         }
  320.     }
  321.     if ( FindTagItem(GA_Width,  ((struct opSet *)msg)->ops_AttrList) ||
  322.          FindTagItem(GA_Height, ((struct opSet *)msg)->ops_AttrList) ||
  323.          FindTagItem(GA_Top,    ((struct opSet *)msg)->ops_AttrList) ||
  324.          FindTagItem(GA_Left,   ((struct opSet *)msg)->ops_AttrList) )
  325.     {
  326.         inst->InitNotDone=TRUE;
  327.         freeRPorts(inst);
  328.     }
  329. }
  330.  
  331. UBYTE long_2_string_with_thousand(ULONG num, char output[], char point)
  332. {
  333.     char             output_private[16];
  334.     char             n      = 0;
  335.     char             n_1    = 0;
  336.     SPrintf(output_private,"%12ld",num);
  337.     while(output_private[n]==0x20)n++;
  338.     for(;(output_private[n]!=0)&(output_private[n]!=0x20);n++)
  339.     {
  340.         output[n_1++]=output_private[n];
  341.         if((n==2)||(n==5)||(n==8)) output[n_1++]=(char)point;
  342.     }
  343.     output[n_1]=0;
  344.     return(n_1);
  345. }
  346.  
  347. char *formattext(ULONG current, ULONG base, ULONG max, char format[])
  348. {
  349.     int         i=0,
  350.                 j=0;
  351.     char        temp_str_1[64];
  352.     static char temp_str[256];
  353.  
  354.     while(format[i]!=0)
  355.     {
  356.         if(format[i]=='%')
  357.         {
  358.             ULONG   dummy=0;
  359.             UBYTE   dummy_2=0,
  360.                     dummy_1=0,
  361.                     dummy_3=0;
  362.             i++;
  363.             if(format[i]=='t'){dummy_2=1;i++;}
  364.             if(format[i]=='T'){dummy_2=4;i++;}
  365.             if(format[i]=='k'){dummy_1=1;i++;}
  366.             if(format[i]=='m'){dummy_1=2;i++;}
  367.             if(format[i]=='o'){dummy_3=1;i++;}
  368.             if(format[i]=='%'){dummy_2=3;i++;}
  369.             switch(format[i])
  370.             {
  371.                 case    'd':
  372.                         dummy=current; i++;
  373.                         break;
  374.                 case    'b':
  375.                         dummy=base; i++;
  376.                         break;
  377.                 case    'a':
  378.                         dummy=max; i++;
  379.                         break;
  380.                 case    'p':
  381.                         dummy_2=2; dummy=current; i++;
  382.                         break;
  383.             }
  384.             if(dummy_3==1)dummy=max-dummy;
  385.             if(dummy_1==1)dummy=dummy>>10;
  386.             if(dummy_1==2)dummy=dummy>>20;
  387.             switch(dummy_2)
  388.             {
  389.                 case    4:
  390.                         dummy_2=long_2_string_with_thousand(dummy,&temp_str_1[0],'.');
  391.                         for(dummy_1=0;dummy_1<dummy_2;dummy_1++) temp_str[j++]=temp_str_1[dummy_1];
  392.                         break;
  393.                 case    1:
  394.                         dummy_2=long_2_string_with_thousand(dummy,&temp_str_1[0],',');
  395.                         for(dummy_1=0;dummy_1<dummy_2;dummy_1++) temp_str[j++]=temp_str_1[dummy_1];
  396.                         break;
  397.                 case    2:
  398.                         dummy_2=0;
  399.                         SPrintf(&temp_str_1[0],"%ld",(((dummy>>8)*100)/((max>>8)+1)) );
  400.                         while ((temp_str_1[dummy_2] != 0)&(dummy_2<64)) temp_str[j++]=temp_str_1[dummy_2++];
  401.                         break;
  402.                 case    0:
  403.                         dummy_2=0;
  404.                         SPrintf(&temp_str_1[0],"%ld",dummy);
  405.                         while ((temp_str_1[dummy_2] != 0)&(dummy_2<64)) temp_str[j++]=temp_str_1[dummy_2++];
  406.                         break;
  407.                 case    3:
  408.                         temp_str[j++]='%';
  409.                         break;
  410.             }
  411.         }
  412.         else temp_str[j++]=format[i++];
  413.     }
  414.     temp_str[j++]=0;
  415.     return(temp_str);
  416. }
  417.  
  418. void draw_border_new( struct RastPort *rp,ULONG x, ULONG y, ULONG width, ULONG height, int b_col1, int b_col2 )
  419. {
  420.     width--;height--;
  421.     SetAPen(rp,b_col2);
  422.     RectFill(rp,x+width,y+1,x+width,y+height);
  423.     RectFill(rp,x,y+height,x+width,y+height);
  424.     SetAPen(rp,b_col1);
  425.     RectFill(rp,x,y,x,y+height-1);
  426.     RectFill(rp,x,y,x+width-1,y);
  427. }
  428.  
  429. my_RectFill(struct RastPort *rp,WORD x,WORD y,WORD width,WORD height)
  430. {
  431.     if(((x+width-1)>0)&&((y+height-1)>0)) RectFill(rp,x,y,x+width-1,y+height-1);
  432. }
  433.  
  434. putChar_hook(struct Hook *hook,struct Locale *locale,ULONG thechar)
  435. {
  436.     struct GaugeData *data;
  437.     geta4(); data=(struct GaugeData *)hook->h_Data;
  438.     data->clocktxt[data->clockpos++]=(UBYTE)(thechar);
  439. }
  440.  
  441. struct Hook putCharHook = { { 0,0 },(void *)HookEntry,(void *)putChar_hook, NULL };
  442.  
  443. my_Blit(struct RastPort *src, WORD topx, WORD topy, struct RastPort *dest, WORD dtopx, WORD dtopy, WORD width, WORD height)
  444. {
  445.     if((width>0)&&(height>0)&&(width<(dest->BitMap->BytesPerRow<<8))&&(height<dest->BitMap->Rows))
  446.     {
  447.         ClipBlit(src,topx,topy,dest,dtopx,dtopy,width,height,0xC0);
  448.     }
  449. }
  450.  
  451. ULONG renderGauge(Class *cl,struct Gadget *g,struct gpRender *msg)
  452. {
  453.     struct  RastPort    *rp;
  454.     ULONG               retval;
  455.     struct  BitMap      *work_bm;
  456.     struct  RastPort    *wk_rp,*bg_rp,*hs_rp;
  457.     struct  GaugeData   *inst;
  458.     struct  DateStamp   d_stamp;
  459.     WORD                text_x,w,h;
  460.     WORD                x1,x2,g_x,g_y,g_size,g_height,t_length;
  461.     char                *fmt;
  462.     LONG                max;
  463.  
  464.     inst=INST_DATA(cl,g);
  465.  
  466.     if(msg->MethodID == GM_RENDER)
  467.         rp=msg->gpr_RPort;
  468.     else
  469.         rp=(struct RastPort *) ObtainGIRPort(msg->gpr_GInfo);
  470.  
  471.     if(rp)
  472.     {
  473.  
  474.         retval=TRUE;
  475.  
  476.         if(inst->InitNotDone)
  477.         {
  478.             if(work_bm=(struct BitMap *)AllocBitMap(g->Width,g->Height+2,rp->BitMap->Depth,BMF_CLEAR,rp->BitMap))
  479.             {
  480.                 if(inst->bg_buffer=(struct RastPort *)AllocVec(sizeof(struct RastPort)+8,MEMF_CLEAR|MEMF_PUBLIC))
  481.                 {
  482.                     InitRastPort(inst->bg_buffer);
  483.                     inst->bg_buffer->BitMap=work_bm;
  484.  
  485.                     my_Blit(rp,g->LeftEdge,g->TopEdge,inst->bg_buffer,0,0,g->Width,g->Height);
  486.                 }
  487.                 else
  488.                 {
  489.                     FreeBitMap(work_bm);
  490.                     retval=0L;
  491.                     goto fail;
  492.                 }
  493.             }
  494.             else { retval=0L; goto fail; }
  495.  
  496.             if(work_bm=(struct BitMap *)AllocBitMap(g->Width,g->Height+2,rp->BitMap->Depth,BMF_CLEAR,inst->bg_buffer->BitMap))
  497.             {
  498.                 if(inst->wk_buffer=(struct RastPort *)AllocVec(sizeof(struct RastPort)+8,MEMF_CLEAR|MEMF_PUBLIC))
  499.                 {
  500.                     InitRastPort(inst->wk_buffer);
  501.                     inst->wk_buffer->BitMap=work_bm;
  502.  
  503.                     inst->text_y=((g->Height-((inst->textFont->tf_Baseline+inst->textFont->tf_YSize)>>1))>>1);
  504.                     if(inst->textFont->tf_Baseline<inst->textFont->tf_YSize)
  505.                     {
  506.                         inst->text_y+=inst->textFont->tf_Baseline-1;
  507.                         if(inst->text_y<inst->textFont->tf_Baseline)inst->text_y=inst->textFont->tf_Baseline;
  508.                     }
  509.                     else
  510.                     {
  511.                         inst->text_y+=inst->textFont->tf_YSize-1;
  512.                         if(inst->text_y<inst->textFont->tf_YSize)inst->text_y=inst->textFont->tf_YSize;
  513.                     }
  514.  
  515.                     SetDrMd(inst->wk_buffer,JAM1);
  516.                     SetFont(inst->wk_buffer,inst->textFont);
  517.                 }
  518.                 else
  519.                 {
  520.                     FreeBitMap(work_bm);
  521.                     retval=0L;
  522.                     goto fail;
  523.                 }
  524.             }
  525.             else { retval=0L; goto fail; }
  526.  
  527.             for(w=0;w<GAU_UsedColors;w++)GetGaugePenNew(msg,inst,&inst->Colors[w],w);
  528.  
  529.             if(inst->type==GAU_Type_histmeter)
  530.             {
  531.                 if(work_bm=(struct BitMap *)AllocBitMap(g->Width,g->Height+2,rp->BitMap->Depth,BMF_CLEAR,inst->wk_buffer->BitMap))
  532.                 {
  533.                     if(inst->hs_buffer=(struct RastPort *)AllocVec(sizeof(struct RastPort)+8,MEMF_CLEAR|MEMF_PUBLIC))
  534.                     {
  535.                         inst->histpos=0;
  536.                         InitRastPort(inst->hs_buffer);
  537.                         inst->hs_buffer->BitMap=work_bm;
  538.                         SetAPen(inst->hs_buffer,inst->Pens[col_bg]);
  539.                         if(inst->StyleBackground)
  540.                         {
  541.                             my_Blit(inst->bg_buffer,0,0,inst->hs_buffer,0,0,g->Width,g->Height);
  542.                         }
  543.                         else
  544.                         {
  545.                             my_RectFill(inst->hs_buffer,0,0,g->Width,g->Height);
  546.                         }
  547.                     }
  548.                     else
  549.                     {
  550.                         FreeBitMap(work_bm);
  551.                         retval=0L;
  552.                         goto fail;
  553.                     }
  554.                 }
  555.                 else { retval=0L; goto fail; }
  556.             }
  557.             inst->old_cur=-1;
  558.             inst->old_bas=-1;
  559.             inst->InitNotDone=FALSE;
  560.         }
  561.  
  562.         w=g->Width-1;
  563.         h=g->Height-1;
  564.         wk_rp=inst->wk_buffer;
  565.         bg_rp=inst->bg_buffer;
  566.         hs_rp=inst->hs_buffer;
  567.         max=inst->max>>8;
  568.  
  569.         switch (inst->type)
  570.         {
  571.             case    GAU_Type_gauge:
  572.                     if((inst->current!=inst->old_cur)||(inst->base!=inst->old_bas))
  573.                     {
  574.                         inst->old_cur=inst->current;
  575.                         inst->old_bas=inst->base;
  576.  
  577.                         my_Blit(bg_rp,0,0,wk_rp,0,0,g->Width,g->Height);
  578.  
  579.                         if(inst->StyleBorder)draw_border_new(wk_rp,inst->labelpos,0,g->Width-inst->labelpos,g->Height,inst->Pens[col_dark],inst->Pens[col_bright]);
  580.  
  581.                         if(inst->StyleShadowLabel)
  582.                         {
  583.                             SetAPen(wk_rp,inst->Pens[col_dark]);
  584.                             Move(wk_rp,1,inst->text_y+1);
  585.                             Text(wk_rp,inst->txtlbl,my_strlen(inst->txtlbl));
  586.                         }
  587.  
  588.                         SetAPen(wk_rp,inst->Pens[col_label]);
  589.                         Move(wk_rp,0,inst->text_y);
  590.                         Text(wk_rp,inst->txtlbl,my_strlen(inst->txtlbl));
  591.  
  592.                         if(!inst->StyleNoGauge)
  593.                         {
  594.                             g_x=1+inst->labelpos;
  595.                             g_y=1;
  596.                             g_size=w-inst->labelpos-1;
  597.                             g_height=h-1;
  598.  
  599.                             x1=g_size-(WORD)(((inst->base>>8)   *g_size)/((max)==0 ? 1 : (max)));
  600.                             x2=g_size-(WORD)(((inst->current>>8)*g_size)/((max)==0 ? 1 : (max)));
  601.  
  602.                             if(!inst->StyleNoBase)
  603.                             {
  604.                                 if(x1<x2) /* the most used... */
  605.                                 {
  606.                                     SetAPen(wk_rp,inst->Pens[col_base]);
  607.                                     my_RectFill(wk_rp,g_x,g_y,x1,g_height);
  608.                                     SetAPen(wk_rp,inst->Pens[col_current]);
  609.                                     my_RectFill(wk_rp,g_x+x1,g_y,x2-x1,g_height);
  610.  
  611.                                     if(!inst->StyleBackground)
  612.                                     {
  613.                                         SetAPen(wk_rp,inst->Pens[col_bg]);
  614.                                         my_RectFill(wk_rp,g_x+x2,g_y,g_size-x2,g_height);
  615.                                     }
  616.                                     if(inst->Style3D)
  617.                                     {
  618.                                         if(x1>1)   draw_border_new(wk_rp,g_x,g_y,x1,g_height,inst->Pens[col_bright],inst->Pens[col_dark]);
  619.                                         if(x2-x1>1)draw_border_new(wk_rp,g_x+x1,g_y,x2-x1,g_height,inst->Pens[col_bright],inst->Pens[col_dark]);
  620.                                     }
  621.                                 }
  622.                                 else
  623.                                 {
  624.                                     if(x1>x2)
  625.                                     {
  626.                                         SetAPen(wk_rp,inst->Pens[col_base]);
  627.                                         my_RectFill(wk_rp,g_x,g_y,x2,g_height);
  628.                                         SetAPen(wk_rp,inst->Pens[col_negative]);
  629.                                         my_RectFill(wk_rp,g_x+x2,g_y,x1-x2,g_height);
  630.  
  631.                                         if(!inst->StyleBackground)
  632.                                         {
  633.                                             SetAPen(wk_rp,inst->Pens[col_bg]);
  634.                                             my_RectFill(wk_rp,g_x+x1,g_y,g_size-x1,g_height);
  635.                                         }
  636.                                         if(inst->Style3D)
  637.                                         {
  638.                                             if(x2>1)   draw_border_new(wk_rp,g_x,g_y,x2,g_height,inst->Pens[col_bright],inst->Pens[col_dark]);
  639.                                             if(x1-x2>1)draw_border_new(wk_rp,g_x+x2,g_y,x1-x2,g_height,inst->Pens[col_bright],inst->Pens[col_dark]);
  640.                                         }
  641.                                     }
  642.                                     else
  643.                                     {
  644.                                         SetAPen(wk_rp,inst->Pens[col_base]);
  645.                                         my_RectFill(wk_rp,g_x,g_y,x1,g_height);
  646.  
  647.                                         if(!inst->StyleBackground)
  648.                                         {
  649.                                             SetAPen(wk_rp,inst->Pens[col_bg]);
  650.                                             my_RectFill(wk_rp,g_x+x1,g_y,g_size-x1,g_height);
  651.                                         }
  652.                                         if(inst->Style3D) if(x1>1)draw_border_new(wk_rp,g_x,g_y,x1,g_height,inst->Pens[col_bright],inst->Pens[col_dark]);
  653.                                     }
  654.                                 }
  655.                             }
  656.                             else
  657.                             {
  658.                                 SetAPen(wk_rp,inst->Pens[col_current]);
  659.                                 my_RectFill(wk_rp,g_x,g_y,x2,g_height);
  660.  
  661.                                 if(!inst->StyleBackground)
  662.                                 {
  663.                                     SetAPen(wk_rp,inst->Pens[col_bg]);
  664.                                     my_RectFill(wk_rp,g_x+x2,g_y,g_size-x2,g_height);
  665.                                 }
  666.                                 if(inst->Style3D) draw_border_new(wk_rp,g_x,g_y,x2,g_height,inst->Pens[col_bright],inst->Pens[col_dark]);
  667.                             }
  668.                         }
  669.  
  670.                         if(!inst->StyleNoFormat)
  671.                         {
  672.                             fmt=formattext(inst->current,inst->base,inst->max,inst->txtfmt);
  673.                             SetAPen(wk_rp,inst->Pens[col_format]);
  674.                             t_length=TextLength(wk_rp,fmt,my_strlen(fmt));
  675.                             if(t_length<(w-inst->labelpos))
  676.                             {
  677.                                 switch(inst->fmtind)
  678.                                 {
  679.                                     case    ind_centered:
  680.                                             text_x=g_x+((g_size-t_length)>>1);
  681.                                             break;
  682.                                     case    ind_left:
  683.                                             text_x=g_x+2;
  684.                                             break;
  685.                                     case    ind_right:
  686.                                             text_x=w-t_length-2;
  687.                                             break;
  688.                                 }
  689.                                 Move(wk_rp,text_x,inst->text_y);
  690.                                 Text(wk_rp,fmt,my_strlen(fmt));
  691.                             }
  692.                         }
  693.                         my_Blit(wk_rp,0,0,rp,g->LeftEdge,g->TopEdge,g->Width,g->Height);
  694.                     }
  695.                     break;
  696.  
  697.             case    GAU_Type_histmeter:
  698.                     w++;
  699.                     h++;
  700.                     g_size=h-3;
  701.                     if(!inst->StyleNoGauge)
  702.                     {
  703.                         x1=(WORD)(((inst->base   >>8)*g_size)/((max)==0 ? 1 : (max)));
  704.                         x2=(WORD)(((inst->current>>8)*g_size)/((max)==0 ? 1 : (max)));
  705.                         inst->histpos++;
  706.                         if(inst->histpos>w-3)
  707.                         {
  708.                             WORD dummy;
  709.                             dummy=w-(w>>1)-2;
  710.                             SetAPen(hs_rp,inst->Pens[col_bg]);
  711.                             my_Blit(hs_rp,w>>1,0,hs_rp,0,0,dummy,h);
  712.                             if(inst->StyleBackground)
  713.                             {
  714.                                 my_Blit(inst->bg_buffer,dummy,0,inst->hs_buffer,dummy,0,w-dummy,h);
  715.                             }
  716.                             else
  717.                             {
  718.                                 RectFill(hs_rp,dummy,0,w,h);
  719.                             }
  720.                             inst->histpos=dummy;
  721.                         }
  722.                         if(!inst->StyleNoBase)
  723.                         {
  724.                             SetAPen(hs_rp,inst->Pens[col_base]);
  725.                             if(x1>x2)
  726.                             {
  727.                                 RectFill(hs_rp,inst->histpos,x1+2,inst->histpos,g_size+1);
  728.                                 SetAPen(hs_rp,inst->Pens[col_current]);
  729.                                 RectFill(hs_rp,inst->histpos,x2+2,inst->histpos,x1+1);
  730.                             }
  731.                             if(x1<x2)
  732.                             {
  733.                                 RectFill(hs_rp,inst->histpos,x1+2,inst->histpos,g_size+1);
  734.                                 SetAPen(hs_rp,inst->Pens[col_negative]);
  735.                                 RectFill(hs_rp,inst->histpos,x1+2,inst->histpos,x2+1);
  736.                             }
  737.                             if(x1==x2)
  738.                             {
  739.                                 RectFill(hs_rp,inst->histpos,x1+2,inst->histpos,g_size+1);
  740.                             }
  741.                         }
  742.                         else
  743.                         {
  744.                             SetAPen(hs_rp,inst->Pens[col_current]);
  745.                             RectFill(hs_rp,inst->histpos,x2+2,inst->histpos,g_size+1);
  746.                         }
  747.                         my_Blit(hs_rp,0,0,wk_rp,0,0,w,h);
  748.                     }
  749.                     if(inst->StyleBorder)draw_border_new(wk_rp,0,0,g->Width,g->Height,inst->Pens[col_dark],inst->Pens[col_bright]);
  750.                     if(!inst->StyleNoFormat)
  751.                     {
  752.                         fmt=formattext(inst->current,inst->base,inst->max,inst->txtfmt);
  753.                         SetAPen(wk_rp,inst->Pens[col_format]);
  754.                         t_length=TextLength(wk_rp,fmt,my_strlen(fmt));
  755.                         if(t_length<w)
  756.                         {
  757.                             switch(inst->fmtind)
  758.                             {
  759.                                 case    ind_centered:
  760.                                         text_x=((w-t_length)>>1);
  761.                                         break;
  762.                                 case    ind_left:
  763.                                         text_x=2;
  764.                                         break;
  765.                                 case    ind_right:
  766.                                         text_x=w-t_length-2;
  767.                                         break;
  768.                             }
  769.                             Move(wk_rp,text_x,h-3);
  770.                             Text(wk_rp,fmt,my_strlen(fmt));
  771.                         }
  772.                     }
  773.                     my_Blit(wk_rp,0,0,rp,g->LeftEdge,g->TopEdge,g->Width,g->Height);
  774.                     break;
  775.             case    GAU_Type_clock:
  776.                     DateStamp(&d_stamp);
  777.                     inst->clockpos=0; putCharHook.h_Data=inst; FormatDate(inst->locale,inst->txtfmt,&d_stamp,&putCharHook);
  778.                     if((t_length=TextLength(wk_rp,&inst->clocktxt[0],my_strlen(&inst->clocktxt[0])))<w)
  779.                     {
  780.                         switch(inst->fmtind)
  781.                         {
  782.                             case    ind_centered:
  783.                                     text_x=(w-t_length)>>1;
  784.                                     break;
  785.                             case    ind_left:
  786.                                     text_x=0;
  787.                                     break;
  788.                             case    ind_right:
  789.                                     text_x=w-t_length-1;
  790.                                     break;
  791.                         }
  792.                         my_Blit(bg_rp,text_x,0,wk_rp,text_x,0,t_length,g->Height);
  793.                         if(inst->StyleShadowLabel)
  794.                         {
  795.                             SetAPen(wk_rp,inst->Pens[col_dark]);
  796.                             Move(wk_rp,text_x+1,inst->text_y+1);
  797.                             Text(wk_rp,&inst->clocktxt[0],my_strlen(&inst->clocktxt[0]));
  798.                         }
  799.                         SetAPen(wk_rp,inst->Pens[col_format]);
  800.                         Move(wk_rp,text_x,inst->text_y);
  801.                         Text(wk_rp,&inst->clocktxt[0],my_strlen(&inst->clocktxt[0]));
  802.                     }
  803.                     my_Blit(wk_rp,text_x,0,rp,g->LeftEdge+text_x,g->TopEdge,t_length,g->Height);
  804.                     break;
  805.         }
  806.         if(msg->MethodID !=GM_RENDER) ReleaseGIRPort(rp);
  807.     }
  808.     else retval=FALSE;
  809.  
  810.     fail:
  811.  
  812.     return(retval);
  813. }
  814.  
  815. #ifdef __GNUC__
  816. ULONG dispatchGaugeGadget(Class *cl,Object *o, Msg msg)
  817. #else
  818. __geta4 ULONG dispatchGaugeGadget(__a0 Class *cl,__a2 Object *o,__a1 Msg msg)
  819. #endif
  820. {
  821.     struct   Gadget *g= (struct Gadget *)o;
  822.     struct   GaugeData *inst;
  823.     ULONG    retval;
  824.     Object  *object;
  825.  
  826. #ifdef __GNUC__
  827.     geta4();
  828. #endif
  829.     retval=DoSuperMethodA(cl,o,msg);
  830.     switch( msg->MethodID )
  831.     {
  832.         case    OM_SET:
  833.                 setGauge(cl,(struct Gadget *)o,(struct gpRender *)msg);
  834.                 break;
  835.         case    GM_RENDER:
  836.                 retval=renderGauge(cl,(struct Gadget *)o,(struct gpRender *)msg);
  837.                 break;
  838.         case    OM_NEW:
  839.                 if(object = (Object *)DoSuperMethodA(cl, o, msg) )
  840.                 {
  841.                     inst = INST_DATA(cl, object);
  842.                     retval=newGauge(cl,(struct Gadget *)object,(struct gpRender *)msg,inst);
  843.                 }
  844.                 break;
  845.         case    OM_GET:
  846.                 retval=getGauge(cl,(struct Gadget *)o,(struct gpRender *)msg);
  847.                 break;
  848.         case    OM_DISPOSE:
  849.                 disposeGauge(cl,g,(struct gpRender *)msg);
  850.                 break;
  851.         default:
  852.                 break;
  853.     }
  854.     return(retval);
  855. }
  856.  
  857.